package com.cmccgz.udacs_landlord_webapp.main.unlock;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;

import com.cmccgz.baselibrary.utils.ByteHexStringUtils;
import com.cmccgz.udacs_landlord_webapp.base.AppConfig;
import com.cmccgz.udacs_landlord_webapp.bean.DeviceInfoBean;
import com.cmccgz.udacs_landlord_webapp.data.DevicesDataSource;
import com.cmccgz.udacs_landlord_webapp.data.DevicesRepository;
import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author: June
 * @Descripion:
 * @date 2017/6/7 15:05
 */

public class BtUnlockPresenter implements BtUnlockContract.Presenter {


    private final BtUnlockContract.View mUnlockView;
    private final DevicesRepository devicesRepository;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    BluetoothDevice device = (BluetoothDevice) msg.obj;
                    Logger.e("连接设备");
//                    mBluetoothLeService.connect(device);
                    devices.put(device.getName(), device);
                    addresses.add(device.getAddress());
                    mUnlockView.addDevice(device);
                    break;
            }
        }
    };
    // 10秒后停止查找搜索.
    private List<String> addresses = new ArrayList<>();
    private static final long SCAN_PERIOD = 10000;
    private static final long UNLOCK_PERIOD = 15000;
    private BluetoothLeService mBluetoothLeService;
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Logger.e("服务连接成功！");
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Logger.e("Unable to initialize Bluetooth");
            }
            scanLeDevice(true);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Logger.e("断开服务链接！");
            scanLeDevice(false);
            mBluetoothLeService = null;
        }
    };
    private BluetoothAdapter adapter;
    private Runnable stopRunnable = new Runnable() {
        @Override
        public void run() {
            mUnlockView.dismissWaitingDialog();
            adapter.stopLeScan(mLeScanCallback);
        }
    };
    private Runnable unlockStopRunnable = new Runnable() {
        @Override
        public void run() {
            mUnlockView.dismissUnlockDialog("解锁失败，设备无响应");
            deviceDisConnect();
        }
    };
    private Map<String, DeviceInfoBean> deviceMap = new HashMap<>();
    private Map<String, BluetoothDevice> devices = new HashMap<>();
    private BluetoothDevice currentBluetoothDevice = null;
    private String msg_code = "";
    private String sn = "";
    private String psd = "";
    private String result_code = "";

    private void scanLeDevice(boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(stopRunnable, SCAN_PERIOD);
            mUnlockView.showWaitingDialog();
            adapter.startLeScan(new UUID[]{UUID.fromString(AppConfig.UUID_SERVICE)}, mLeScanCallback);
//            adapter.startLeScan(mLeScanCallback);
        } else {
            mHandler.removeCallbacks(stopRunnable);
            mUnlockView.dismissWaitingDialog();
            adapter.stopLeScan(mLeScanCallback);
        }
    }

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            Logger.e("name:" + device.getName() + "address:" + device.getAddress());
            if ((!TextUtils.isEmpty(device.getName())) && (deviceMap.get(device.getName()) != null) && (rssi >= -95) && (!addresses.contains(device.getAddress()))) {
                Message message = Message.obtain();
                message.what = 0;
                message.obj = device;
                mHandler.sendMessage(message);
            }
        }
    };

    public BtUnlockPresenter(BtUnlockContract.View view) {
        mUnlockView = view;
        mUnlockView.setPresenter(this);
        devicesRepository = new DevicesRepository();
        initDeviceData();
    }

    private void initDeviceData() {
        devicesRepository.getDevices(new DevicesDataSource.OnGetDevicesLisenter() {
            @Override
            public void getDevicesCache(List<DeviceInfoBean> datas) {
                initDeviceMap(datas);
            }

            @Override
            public void getDevicesSuccess(List<DeviceInfoBean> datas) {
                initDeviceMap(datas);
            }

            @Override
            public void getDevicesError(String msg) {

            }
        });
    }

    private void initDeviceMap(List<DeviceInfoBean> list) {
        deviceMap.clear();
        for (DeviceInfoBean device : list) {
            deviceMap.put(device.device_name, device);
        }
    }


    @Override
    public void start() {
        this.adapter = mUnlockView.checkBlueTooth();
    }

    @Override
    public void unlock(String deviceName, String deviceAddress) {
        DeviceInfoBean device = getDeviceInfo(deviceName);
        if (device != null) {
            mUnlockView.showUnlockDialog();
            mHandler.postDelayed(unlockStopRunnable, UNLOCK_PERIOD);
            boolean isConnect = mBluetoothLeService.connect(devices.get(device.device_name));
            if (isConnect) {
                currentBluetoothDevice = devices.get(device.device_name);
            } else {
                currentBluetoothDevice = null;
            }
            Logger.e("连接状态：" + isConnect);
        }
    }

    private void doUnlock(DeviceInfoBean device) {
        String unlockCode = getUnlockCode(device);
        Logger.e("解锁码：" + unlockCode);
        BluetoothGatt gatt = mBluetoothLeService.getBluetoothGatt();
        BluetoothGattService service = gatt.getService(UUID.fromString(AppConfig.UUID_SERVICE));
        if (service == null) {
//                mUnlockView.dismissUnlockDialog("设备异常，请稍后再试！");
            mUnlockView.dismissUnlockDialog("无服务");
            deviceDisConnect();
            return;
        }
        BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(AppConfig.UUID_CHARACTERISTIC));
        if (characteristic == null) {
//                mUnlockView.dismissUnlockDialog("设备异常，请稍后再试！");
            mUnlockView.dismissUnlockDialog("无characteristic");
            deviceDisConnect();
            return;
        }
        int properties = characteristic.getProperties();
        if ((properties | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

            // 7E                                 头
            // 46432D38393130413137303430313032   设备sn码
            // FFFFFFFF                           设备密码
            // 1F86B5C3                           信息代码
            // 030300                             控制码
            // 00000004                           数据码
            // 01000000                           数据内容
            // 7C                                 检验码
            // 7E                                 尾
//                String hexString = "7E46432D38393130413137303430313032FFFFFFFF1F86B5C303030000000004010000007C7E";

            byte[] bytes = ByteHexStringUtils.hexStringToBytes(unlockCode);
            int count;
            int num = bytes.length % 20;
            if (num > 0) {
                count = bytes.length / 20 + 1;
            } else {
                count = bytes.length / 20;
            }
            for (int i = 0; i < count; i++) {
                byte[] packageByte;
                if (i == count - 1) {
                    packageByte = new byte[num];
                    System.arraycopy(bytes, i * 20, packageByte, 0, num);
                } else {
                    packageByte = new byte[20];
                    System.arraycopy(bytes, i * 20, packageByte, 0, 20);
                }
                characteristic.setValue(packageByte);
                mBluetoothLeService.writeCharacteristic(characteristic);
                SystemClock.sleep(10);
            }
        }
    }

    private String getUnlockCode(DeviceInfoBean device) {
        result_code = "";
        sn = device.sn;
        psd = device.psd;
        msg_code = ByteHexStringUtils.randomHexString(8);
        String dataString = sn + psd + msg_code + AppConfig.CODE_OPEN_CONTROL +
                AppConfig.CODE_OPEN_DETA_KEY + AppConfig.CODE_OPEN_DETA;

        byte[] dataBytes = ByteHexStringUtils.hexStringToBytes(dataString);
        byte[] sumCheck = ByteHexStringUtils.SumCheck(dataBytes, 1);
        String checkSum = ByteHexStringUtils.bytesToHexString(sumCheck);
        dataString += checkSum;
        String translationCode = ByteHexStringUtils.translation(dataString);
        return AppConfig.CODE_BASE + translationCode + AppConfig.CODE_BASE;
    }


    private DeviceInfoBean getDeviceInfo(String deviceName) {
        List<DeviceInfoBean> list = AppConfig.getDeviceList();
        for (DeviceInfoBean device : list) {
            if (device.house_name.equals(deviceName)) {
                return device;
            }
        }
        return null;
    }

    @Override
    public void bluetoothEnable() {
        mUnlockView.bindService(mServiceConnection);
    }

    @Override
    public void displayData(Intent intent) {
        String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
        Logger.e("收到消息：" + data);
        if (!TextUtils.isEmpty(data)) {
            String upperCase = data.toUpperCase();
            result_code += upperCase;
            if (upperCase.endsWith(AppConfig.CODE_BASE)) {
                Logger.e("解锁响应码：" + result_code);
                resultReceiveComplete();
            }
        }
    }

    private void resultReceiveComplete() {
        String substring = result_code.substring(2, result_code.length() - 2);
        String[] split = substring.split("7E7E");
        for (String code : split) {
            String reverseTranslation = ByteHexStringUtils.reverseTranslation(code);
            Logger.e("转译后的指令:" + reverseTranslation);
            if (reverseTranslation.length() == 64) {
                String checkCode = reverseTranslation.substring(62, 64);
                String dataCode = reverseTranslation.substring(0, 62);
                byte[] dataBytes = ByteHexStringUtils.hexStringToBytes(dataCode);
                byte[] sumCheck = ByteHexStringUtils.SumCheck(dataBytes, 1);
                String checkSum = ByteHexStringUtils.bytesToHexString(sumCheck);
                if (!checkCode.equals(checkSum != null ? checkSum.toUpperCase() : null)) {
//                    mUnlockView.dismissUnlockDialog("设备异常，请稍后再试！");
                    mUnlockView.dismissUnlockDialog("校验和错误");
                    deviceDisConnect();
                    return;
                }
                String resultMsgCode = reverseTranslation.substring(0, 8);
                String resultSn = reverseTranslation.substring(8, 40);
                String resultPsd = reverseTranslation.substring(40, 48);
                if (resultMsgCode.equals(msg_code) && resultSn.equals(sn) && resultPsd.equals(psd)) {
                    String controlCode = reverseTranslation.substring(48, 54);
                    if (AppConfig.CODE_OPEN_RESULT_OK_OCNTROL.equals(controlCode)) {
                        mUnlockView.dismissUnlockDialog("解锁成功！");
                        deviceDisConnect();
                    } else {
                        mUnlockView.dismissUnlockDialog("解锁失败！");
                        deviceDisConnect();
                    }
                } else {
//                    mUnlockView.dismissUnlockDialog("设备异常，请稍后再试！");
                    mUnlockView.dismissUnlockDialog("设备信息或信息代码错误");
                    deviceDisConnect();
                }
            } else if (reverseTranslation.length() == 80) {

            } else {
                mUnlockView.dismissUnlockDialog("返回数据长度有误");
                deviceDisConnect();
            }
        }
        result_code = "";
    }

    @Override
    public void unbindService() {
        mUnlockView.unbindService(mServiceConnection);
    }

    @Override
    public void scanDevice(boolean scan) {
        if (adapter != null) {
            this.scanLeDevice(scan);
        }
    }

    @Override
    public void deviceDisConnect() {
        mHandler.removeCallbacks(unlockStopRunnable);
        mBluetoothLeService.disconnect();
        currentBluetoothDevice = null;
    }

    @Override
    public void deviceConnect() {
        if (currentBluetoothDevice != null) {
            DeviceInfoBean bean = deviceMap.get(currentBluetoothDevice.getName());
            if (bean != null) {
                Logger.e("准备解锁！");
                SystemClock.sleep(15);
                doUnlock(bean);
            }
        }
    }
}
